﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

public class slotScript : MonoBehaviour, IPointerClickHandler, IClickable, IPointerEnterHandler,IPointerExitHandler
{
    [SerializeField]
    private Image icon;
    public Item MyItem
    {
        get
        {
            if (!IsEmpty)
            {
                return MyItems.Peek();
            }
            return null;
        }
    }
    private DisplayableStack<Item> items = new DisplayableStack<Item>();
    public bool IsEmpty { get { return MyItems.Count == 0; } }
    public bagScript MyBag { get; set; }
    public bool IsFull
    {
        get
        {
            if (IsEmpty)
            {
                return false;   
            }else if(MyCount < MyItem.StackSize)
            {
                return false;
            }
            else
            {
                return true;
            }
        }
    }

    public Image MyIcon { get => icon; set => icon=value; }

    public int MyCount { get { return MyItems.Count; } }
    [SerializeField]
    private Text stackSize;

    public Text MyStackSize => stackSize;
    public int MySlotIndex { get; set; }
    public DisplayableStack<Item> MyItems { get => items;  }

    public void Awake()
    {
        MyItems.OnPop += new UpdateStackEvent(UpdateSlot);
        MyItems.OnPush += new UpdateStackEvent(UpdateSlot);
        MyItems.OnClear += new UpdateStackEvent(UpdateSlot);
    }
    private void UpdateSlot()
    {
        UIManager.MyInstance.UpdateStackSize(this);
    }
    public bool AddItem(Item item)
    {
        if (Stackable(item))
        {
            inventoryScript.MyInstance.ItemCountChange(item);
        }
        else
        {
            MyItems.Push(item);
            UpdateSlot();
            icon.sprite = item.Icon;
            item.Slot = this;
            icon.color = Color.white;
        }
        return true;

    }

    public void RemoveItem(Item item)
    {
        if (!IsEmpty)
        {
            //Items.Pop();
            //UpdateSlot();
            inventoryScript.MyInstance.ItemCountChange(MyItems.Pop());
        }
    }
    public void Clear()
    {
        //testing the displayablestack work
        //int initCount=MyItems.Count;
        //if (initCount > 0)
        //{
        //    for (int i = 0; i < initCount; i++)
        //    {
        //        inventoryScript.MyInstance.ItemCountChange(items.Pop());
        //        //try to remove for loop
        //    }
        //}
        if(items.Count != 0)
        {
            inventoryScript.MyInstance.ItemCountChange(items.Pop());
            MyItems.Clear();
        }
        
    }

    public void OnPointerClick(PointerEventData eventData)
    {
        if (eventData.button == PointerEventData.InputButton.Right && handScript.MyInstance.MyMovable==null)
        {
            UseItem();
        }
        if(eventData.button == PointerEventData.InputButton.Left )
        {
            if(inventoryScript.MyInstance.FromSlot == null && !IsEmpty)
            {
                if (handScript.MyInstance.MyMovable != null)
                {
                    if(MyItem is bag && handScript.MyInstance.MyMovable is bag)
                    {
                        inventoryScript.MyInstance.swapBags(handScript.MyInstance.MyMovable as bag, MyItem as bag);
                    }
                    else if(handScript.MyInstance.MyMovable is Equipment && MyItem is Equipment && (MyItem as Equipment).MyType==(handScript.MyInstance.MyMovable as Equipment).MyType)
                    {
                        (MyItem as Equipment).Equip();
                        //UIManager.MyInstance.refreshTooltip();
                        handScript.MyInstance.Drop();
                        
                    }
                   
                }
                else
                {
                    handScript.MyInstance.takeMovable(MyItem as IMovable);
                    inventoryScript.MyInstance.FromSlot = this;
                }
                
            }
            else if (inventoryScript.MyInstance.FromSlot == null && IsEmpty)
            {
                if(handScript.MyInstance.MyMovable is bag)
                {
                    bag bagg = (bag)handScript.MyInstance.MyMovable;
                    if (bagg.MyBagScript != MyBag && inventoryScript.MyInstance.MyEmptySlotCounter - bagg.Slots > 0)
                    {
                        AddItem(bagg);
                        bagg.MyBagButton.deleteBag();
                        handScript.MyInstance.Drop();
                    }
                }
                if (handScript.MyInstance.MyMovable is Equipment)
                {
                    Equipment tmp= (Equipment)handScript.MyInstance.MyMovable;
                    
                    CharcterPanel.MyInstance.MyCharbutton.Unequip();
                    AddItem(tmp);
                    handScript.MyInstance.Drop();
                }
            }
            else if(inventoryScript.MyInstance.FromSlot != null)
            {
                if (ReturnBack() ||MergeItems(inventoryScript.MyInstance.FromSlot) ||swapItems(inventoryScript.MyInstance.FromSlot) || PutItems(inventoryScript.MyInstance.FromSlot.MyItems))
                {
                    handScript.MyInstance.Drop();
                    inventoryScript.MyInstance.FromSlot = null;
                }
                
            }

        }
    }
    public bool ReturnBack()
    {
        if(inventoryScript.MyInstance.FromSlot == this)
        {
            inventoryScript.MyInstance.FromSlot.MyIcon.color = Color.white;
            return true;
        }
        return false;
    }
    public bool PutItems(DisplayableStack<Item> newItems)
    {
        if(IsEmpty || newItems.Peek().MyTitle== this.MyItem.MyTitle)
        {
            int itemLength = newItems.Count;
            for (int i = 0; i < itemLength; i++)
            {
                if (IsFull)
                {
                    return false;
                }
                else
                {
                    AddItem(newItems.Pop());
                    
                }
            }
            return true;
        
        }
        return false;
    }
    public bool swapItems(slotScript fromslot)
    {
        if (IsEmpty)
        {
            return false;
        }
        if(fromslot.MyItem.MyTitle != MyItem.MyTitle || fromslot.MyCount+MyCount>MyItem.StackSize)
        {
            DisplayableStack<Item> tmp = new DisplayableStack<Item>(fromslot.MyItems);
            fromslot.MyItems.Clear();
            fromslot.PutItems(MyItems);
            MyItems.Clear();
            PutItems(tmp);
            return true;
        }
        return false;
    }
    public bool MergeItems(slotScript fromslot)
    {
        if (IsEmpty)
        {
            return false;
        }
        if (!IsFull && fromslot.MyItem.MyTitle == MyItem.MyTitle)
        {
            int emptySlots = MyItem.StackSize - MyCount;
            for (int i = 0; i < emptySlots; i++)
            {
                if(fromslot.MyItems.Count > 0)
                {
                    AddItem(fromslot.MyItems.Pop());
                }
                else
                {
                    break;
                }
                

            }
            return true;
        }
        return false;
    }
    public void UseItem()
    {
        if(MyItem is IUsable)
        {
            (MyItem as IUsable).use();
        }
        else if (MyItem is Equipment)
        {
            (MyItem as Equipment).Equip();
        }
    }
    public bool Stackable(Item item)
    {
        if(!IsEmpty && item.MyTitle == MyItem.MyTitle && MyItems.Count < MyItem.StackSize)
        {
            
            MyItems.Push(item);
           // UpdateSlot();
            item.Slot = this;
            return true;
        }
        return false;
    }

    public void OnPointerEnter(PointerEventData eventData)
    {
        if (!IsEmpty)
        {
           
            UIManager.MyInstance.showToolTip(new Vector2(1, 0), transform.position, MyItem);
        }
        
    }

    public void OnPointerExit(PointerEventData eventData)
    {
        
        UIManager.MyInstance.hideToolTip();
    }
}
